package com.ssb.controller;

import com.apache.api.api.ApiService;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.api.vo.ResultMsg;
import com.apache.cache.util.Validator;
import com.apache.client.LogClient;
import com.apache.database.constant.SpringContextLoader;
import com.apache.exception.BusinessException;
import com.apache.ius.common.CommonUtils;
import com.apache.ius.common.annotion.AnnotationUtil;
import com.apache.ius.common.connectors.impl.AdapterFactory;
import com.apache.ius.controller.SuperApiAction;
import com.apache.ius.plugin.CustomMethodPlugin;
import com.apache.ius.plugin.IusPluginUtil;
import com.apache.passport.common.DesUtils;
import com.apache.passport.entity.Token;
import com.apache.portal.common.util.PortalPubFactory;
import com.apache.rpc.common.LoadRpcService;
import com.apache.tools.*;
import com.apache.uct.common.LoginUser;
import com.apache.uct.common.PBOSSOTools;
import com.apache.uct.common.ToolsUtil;
import com.apache.uct.common.entity.User;
import com.ssb.service.check.CheckedFrontSysService;
import com.ssb.service.pay.AppPayService;
import com.ssb.service.pay.WxPayService;
import com.ssb.util.AESUtil;
import com.ssb.util.HttpUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;


/**
 * 平台自动生成的统一开放第三方相关的api接口controller类
 * /api/*已配置在白名单内
 * 请求地址参考：http://127.0.0.1:81/ssb/api/***
 * 其他方法，请自行补充
 * @Date 2020-1-31 13:51:04
 */
@Controller
@RequestMapping({"/api/"})
public class ApiAction extends SuperApiAction {
    private Logger log = Logger.getLogger(getClass());


    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private CheckedFrontSysService checkedFrontSysService;
    @Autowired
    private AppPayService appPayService;

    //登录
    @RequestMapping(value = "/login", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public void login(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> requestBody) throws Exception {
        ResultMsg msg = new ResultMsg("F", "登录失败");
        //Map<String, String> params = this.getParameterMap(request);
        Map<String, String> params = this.getParameterMapByJson(request, requestBody);
        log.info("client request params-->" + params);
        Map<String, Object> maps = new HashMap<String, Object>();
        String username = params.get("username");//支持传入：用户账号、手机号、邮箱
        String password = params.get("password");
        String smsCode = params.get("smsCode");//短信验证码
        String source = StrUtil.doNull(params.get("source"), "");//登录来源：weixin,app
        String openId = StrUtil.doNull(params.get("openId"), "");//微信openId
        String type = StrUtil.doNull(params.get("type"), "1");//1:默认账号、手机号、邮箱+密码方式，2、手机号+验证码
        String frontSysCode = StrUtil.doNull(params.get("frontSysCode"));//前端系统代码

        //校验此前端系统是否存在且有效
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        if (result.get("errorCode").equals("F")){
            this.gotoErrorPage(request, response, result.get("errorMsg"));
            return;
        }

        //判断类型，以备校验
        switch (type) {
            case "1"://账号、手机号、邮箱+密码
                if (StrUtil.isNull(username) || StrUtil.isNull(password)) {
                    this.gotoErrorPage(request, response, "登录信息不能为空");
                    return;
                }
                break;
            case "2"://手机号+短信验证码
                String mobile = username;
                if (StrUtil.isNull(mobile) || StrUtil.isNull(smsCode)) {
                    this.gotoErrorPage(request, response, "手机号码或验证码不能为空");
                    return;
                }
                String smsCode_old = String.valueOf(CommonUtils.getCache("mobile_obj_" + mobile));
                log.info("smsCode validator -> [old->" + smsCode_old + "]=[input->" + smsCode + "]");
                if (!smsCode.equals(smsCode_old)) {
                    this.gotoErrorPage(request, response, "短信验证码有误");
                    return;
                } else {
                    CommonUtils.removeCache("mobile_obj_" + mobile);//验证成功，移除
                }
                maps.put("isCheckPass", "F");//告知sso不验证密码
                break;
        }

        //查询用户是否存在，判断是否是否满足当前的登录入口。
        Map<String, Object> uct_whereMap = new HashMap<>();
        if(checkMobile(username)){//登录账号是手机号
            //按照手机号和，来源类型查询用户是否存在，
            uct_whereMap.put("uctUser.w_mobile", username);
        }else{
            uct_whereMap.put("uctUser.w_userEname", username);
        }
        ResultEntity resultEntity1 = IusPluginUtil.getInstance().select("plateform", "list", "s_uctUser", uct_whereMap);
        Map<String, Object> resultMap = super.getResultEntityData(resultEntity1);
        if ("T".equals(resultMap.get("flag"))) {
            List<DataMap> userList = (ArrayList<DataMap>) resultMap.get("rows");
            log.info("根据["+username+"]查找到用户个数["+userList.size()+"]");
            if(userList.size()==0){
                if(checkMobile(username)){//登录账号是手机号
                    msg = new ResultMsg("F", "F02:用户手机号有误");//账号不存在，提示： 登录号或者密码有误
                }else{
                    msg = new ResultMsg("F", "F01:用户账号有误");//账号不存在，提示： 登录号或者密码有误
                }
                gotoErrorPage(request, response, msg.getMsg());
                return;
            }else{
                //用户存在则获取第一个满足条件的用户userEname
                DataMap userInfo = userList.get(0);
                String mobile_userEname = String.valueOf(userInfo.get("userEname"));
                String userType = String.valueOf(userInfo.get("userType"));
                String auditStatus = String.valueOf(userInfo.get("auditStatus"));
                String userPass = String.valueOf(userInfo.get("userPass"));
                log.info("当前可在登录的用户userEname["+mobile_userEname+"]");
                username=mobile_userEname;
                if ("manager".equals(userType)) {
                    msg = new ResultMsg("F", "F04:用户无权限登录");//此用户暂无权限
                    gotoErrorPage(request, response, msg.getMsg());
                    return;
                }
                if (Validator.isNotNull(password)&&!password.equals(userPass)) {
                    msg = new ResultMsg("F", "F03:用户密码有误");//用户密码有误
                    gotoErrorPage(request, response, msg.getMsg());
                    return;
                }
                if ("10".equals(auditStatus)) {
                    msg = new ResultMsg("F", "F11:用户正在审核中");//此用户正在审核中
                    gotoErrorPage(request, response, msg.getMsg());
                    return;
                }
                if ("90".equals(auditStatus)) {
                    msg = new ResultMsg("F", "F12:用户审核未通过");//此用户未审核通过
                    gotoErrorPage(request, response, msg.getMsg());
                    return;
                }
            }
        }else{
            msg = new ResultMsg("F", "F10:登录请求超时");//查询平台接口调用超时
            gotoErrorPage(request, response, msg.getMsg());
            return;
        }
        /**
         * 登录异常返回状态码：格式{"msg":"F01:用户账号有误","flag":"F"}
         *
         F01:用户账号有误
         F02:用户手机号有误
         F03:用户密码有误
         F04:用户无权限登录
         F05:用户已被停用
         F06:用户已被删除
         F07:用户已被锁定
         F08:用户名或密码错误
         F09:其他未知错误

         F10:登录请求超时
         F11:用户正在审核中
         F12:用户审核未通过
         F13:用户暂无权限登录
         *
         */

        //准备参数请求sso进行登录验证。
        maps.put("userEname", username);
        maps.put("Client-IP", StrUtil.doNull(params.get("Client-IP"), RequestTools.getIp(request)));
        maps.put("userPass", password);
        maps.put("sysEname", ToolsUtil.getInstance().getValueByKey("sysEname"));
        maps.put("addressIP", maps.get("Client-IP"));
        //请求sso返回登录结果
        JSONObject resObj = getLoginJsonObject(request, response, maps);

        this.outputJson(resObj.toString(), response, "");
//        if (!ToolsUtil.isEmpty(msg)) {
//            JSONObject obj = JSONObject.fromObject(msg);
//            this.outputJson(obj.toString(), response, "");
//        }
    }
    /**
     * 判断是否是手机号格式
     * @param mobile
     * @return
     */
    private static boolean checkMobile(String mobile) {
        String regex = "^\\d{11}$";
        Pattern pattern = Pattern.compile(regex);
        if(StrUtil.isNull(mobile)){
            return  false;
        }else{
            return pattern.matcher(mobile).matches();
        }
    }
    /**
     * sso登录封装方法
     */
    private JSONObject getLoginJsonObject(HttpServletRequest request, HttpServletResponse response, Map<String, Object> maps) {
        ResultMsg msg = new ResultMsg("F", "登录失败");
        JSONObject resObj = new JSONObject();
        String login_username = String.valueOf(maps.get("userEname"));
        ResultEntity entity = LoadRpcService.service().doServiceClient("ssoService", "outSideSocketLoginService", maps,
                PortalPubFactory.getInstance().getRpcInfo("sso"));
        if (entity != null && ("true".equals(entity.getResult())) && !ToolsUtil.isEmpty(entity.getEntity())) {
            if (entity.getEntity() instanceof String) {
                String userMsg = String.valueOf(entity.getMessage());
                log.error("登录异常提示：" + userMsg);
                if (userMsg.indexOf("用户已停用") > -1) {
                    msg = new ResultMsg("F", "F05:用户已被停用");//用户已停用
                } else if (userMsg.indexOf("删除") > -1) {
                    msg = new ResultMsg("F", "F06:用户已被删除");//用户已留痕删除
                } else if(userMsg.indexOf("锁定") > -1){
                    msg = new ResultMsg("F", "F07:用户已被锁定");//账户多次密码输入错误已被锁定
                } else if(userMsg.indexOf("用户名或密码错误") > -1){
                    msg = new ResultMsg("F", "F08:用户名或密码错误");//用户名或密码错误
                } else {
                    msg = new ResultMsg("F", "F09:"+userMsg);//其他未知错误
                }
                resObj = JSONObject.fromObject(msg);
            } else {
                //仓储cookie
                Token token = (Token) entity.getEntity();
                Cookie cookie = new Cookie(ToolsUtil.getInstance().getValueByKey("cookieName"),
                        token.getTokenId());
                cookie.setPath("/");
                cookie.setMaxAge(-1);
                Cookie ucsso = new Cookie("_uc.sso",
                        DesUtils.getInstance().decrypt(token.getUserEname()));
                ucsso.setPath("/");
                ucsso.setMaxAge(-1);
                response.addCookie(cookie);
                response.addCookie(ucsso);
                request.getSession().removeAttribute("loginUser");
                request.getSession().removeAttribute("tokenId");
                request.getSession().setAttribute("tokenId", token.getTokenId());
                log.info("[" + login_username + "]登录成功！");
                //剔除loginInfo，解密email，userEname，mobile传明文
                JsonConfig jc = new JsonConfig();
                String config[] = {"loginInfo"};
                jc.setExcludes(config);
                String token_email = token.getEmail();
                String token_mobile = token.getMobile();
                String token_userEname = token.getUserEname();
                token.setEmail(DesUtils.getInstance().decrypt(token_email));
                token.setMobile(DesUtils.getInstance().decrypt(token_mobile));
                token.setUserEname(DesUtils.getInstance().decrypt(token_userEname));
//                msg = new ResultMsg("T", JSONObject.fromObject(token, jc).toString());
                msg = new ResultMsg("T", "登录成功");
                resObj = JSONObject.fromObject(msg, jc);

                //记录日志
                Map<String, Object> logMap = new HashMap<String, Object>();
                logMap.put("logOperationType", "login");
                logMap.put("logClassName", User.class.getName());
                logMap.put("logIp", maps.get("Client-IP"));
                logMap.put("log_userEname", token.getUserEname());
                log.info("登录成功日志：" + logMap);
                LogClient.getInstance().execute(logMap);//添加日志

                //存储session
                if ("T".equals(msg.getFlag())) {
                    JSONObject jb = JSONObject.fromObject(token);
                    Map<String, Object> map = (Map) jb;
                    LoginUser loginUser = PBOSSOTools.getLoginUserFromUserCenter(String.valueOf(map.get("userEname")),
                            String.valueOf(map.get("tokenId")));
                    if (loginUser != null) {
                        jb.put("sysFlag", loginUser.getSysFlag());
                        jb.put("actMap", loginUser.getActMap());
                        String actJsonStr = StrUtil.doNull(loginUser.getActJsonStr(), "");
                        jb.put("actJsonStr", actJsonStr);
                        String actFnmStr = "";
                        if (!StrUtil.isNull(actJsonStr)) {
                            JSONArray actJsonArray = JSONArray.fromObject(actJsonStr);
                            if (actJsonArray.size() > 0) {
                                for (int i = 0; i < actJsonArray.size(); i++) {
                                    JSONObject actJson = (JSONObject) actJsonArray.getJSONObject(i);
                                    if (i == 0) {
                                        actFnmStr += actJson.getString("fnm");
                                    } else {
                                        actFnmStr += "," + actJson.getString("fnm");
                                    }
                                }
                            }
                        }
                        jb.put("actFnmStr", actFnmStr);
                        User user = loginUser.getUser();
                        if (user != null) {
                            jb.put("userRemark", StrUtil.doNull(user.getUserRemark(), ""));
                            jb.put("auditStatus", StrUtil.doNull(user.getAuditStatus(), ""));
                            jb.put("managerType", StrUtil.doNull(user.getManagerType(),""));
                            jb.put("recordType", StrUtil.doNull(user.getRecordType(),""));
                            jb.put("district", StrUtil.doNull(user.getDist(),""));
                            jb.put("auditText", StrUtil.doNull(user.getAuditText(), ""));
                            jb.put("userSex", StrUtil.doNull(user.getUserSex(), ""));
                            jb.put("userStatus", user.getUserStatus());
                            jb.put("userTitle", StrUtil.doNull(user.getUserTitle(), ""));
                            jb.put("address", StrUtil.doNull(user.getAddress(), ""));
                            jb.put("appId", StrUtil.doNull(user.getAppUid(), ""));
                            jb.put("userScore", user.getUserScore());
                            jb.put("certType", StrUtil.doNull(user.getCertType(), ""));
                            jb.put("certNo", StrUtil.doNull(user.getCertNo(), ""));
                            jb.put("orgId", StrUtil.doNull(user.getOrgId(), ""));
                            jb.put("orgEname", StrUtil.doNull(user.getOrgEname(), ""));
                            jb.put("province", StrUtil.doNull(user.getProvince(), ""));
                            jb.put("city", StrUtil.doNull(user.getCity(), ""));
                            jb.put("deptId", StrUtil.doNull(user.getDeptId(), ""));
                            jb.put("dataOrgIds", StrUtil.doNull(loginUser.getDataOrgIds(), ""));//存储机构权限
                        }
                    }
                    resObj.put("loginUser", jb);
                    request.getSession().setAttribute("loginUser", loginUser);
                }
            }
        }
        log.info("[" + login_username + "]登录结果：" + resObj.toString());
        return resObj;
    }

    //文件上传,支持上传至oss
    @RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
    @ResponseBody
    public void uploadFile(HttpServletRequest request, HttpServletResponse response, @RequestParam("file") MultipartFile file) throws Exception {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("flag", "F");
        final long minLen = 1024 * 1024 * 5; // 5M
        final long maxLen = 1024 * 1024 * 1024; // 1G
        long starTime = new Date().getTime();
        Map<String, String> params = this.getParameterMap(request);// this.getParameterMapByJson(request,requestBody);

        // 如果文件不为空，写入上传路径，进行文件上传
        log.info("\n");
        if (!file.isEmpty()) {
            log.info("client request params-->" + params);
            String fileContentType = file.getContentType();
            String fileName = file.getOriginalFilename();
            long fileSize = file.getSize();

            log.info("File upload start...");
            log.info("File contentType-> " + fileContentType);

            //1、从本地config文件读取配置
            String localFileName = "config.properties";
            String fileUploadDirectory = ToolsUtil.getInstance().getLocalByKey(localFileName, "UPLOAD_DIRECTORY");//获取文件需要上传到的根目录
            String fileDownloadUrl = ToolsUtil.getInstance().getLocalByKey(localFileName, "DOWNLOAD_URL");//获取文件需要下载的根目录地址
            String fileAllowType = ToolsUtil.getInstance().getLocalByKey(localFileName, "ALLOW_TYPE");//允许上传的文件类型
            String fileMaxLength = ToolsUtil.getInstance().getLocalByKey(localFileName, "FILE_MAX_LENGTH");//文件大小最大值
            if (StrUtil.isNull(fileUploadDirectory) || StrUtil.isNull(fileDownloadUrl)) {
                log.error(localFileName + "配置文件缺少[UPLOAD_DIRECTORY、DOWNLOAD_URL、ALLOW_TYPE、FILE_MAX_LENGTH]等相关配置");
                resultMap.put("msg", "服务端缺少相关配置");
                JSONObject obj = JSONObject.fromObject(resultMap);
                this.outputJson(obj.toString(), response, "");
                return;
            }
            String FILE_MAX_LENGTH = StrUtil.doNull(fileMaxLength, String.valueOf(maxLen));//单位B
            String File_ALLOW_TYPE = fileAllowType;
            long fimaxLength = Long.valueOf(FILE_MAX_LENGTH).longValue();
            log.info("Config FILE_MAX_LENGTH-> " + FILE_MAX_LENGTH + "=" + getFileSize(fimaxLength));
            log.info("Config ALLOW_TYPE-> " + File_ALLOW_TYPE);

            //2、配置上传参数
            String uploadRoot = fileUploadDirectory + "/atta/"; //获取文件需要上传到的根目录
            String downloadRoot = fileDownloadUrl + "/atta/";//获取文件需要下载的根目录
            String nowDataStr = new SimpleDateFormat("yyyyMMdd").format(new Date());// + "/";
            String fileTypes = StrUtil.doNull(params.get("upload_fileTypes"), File_ALLOW_TYPE);
            String sysEname = StrUtil.doNull(params.get("upload_sysName"), CommonUtils.getSysEname());
            String uploadFolder = StrUtil.doNull(params.get("upload_folder"), "");//自定义业务类型文件夹
            String confData = StrUtil.doNull(params.get("confData"), "");//其他配置参数json格式的字符串
            log.info("File request confData->  " + confData);
            String waterFlag = "F", waterText = "", waterType = "";//水印配置参数
            String ossFlag = "F",ossReLocalFlag="F";//是否上传至阿里云的oss,上传成功后是否删除本地文件
            if (!StrUtil.isNull(confData)) {
                JSONObject jsonConf = JSONObject.fromObject(confData);
                waterFlag = StrUtil.doNull(String.valueOf(jsonConf.get("waterFlag")), "F");//是否添加水印
                waterText = StrUtil.doNull(String.valueOf(jsonConf.get("waterText")), "水印文字LOGO");//是否水印文字
                waterType = StrUtil.doNull(String.valueOf(jsonConf.get("waterType")), "1");//水印方式：1=普通右下角，2=45°斜铺

                ossFlag = StrUtil.doNull(String.valueOf(jsonConf.get("ossFlag")), "F");//是否上传至阿里云的oss
                ossReLocalFlag = StrUtil.doNull(String.valueOf(jsonConf.get("ossReLocalFlag")), "F");//oss上传成功后是否删除本地文件
            }

            log.info("File request upload_fileTypes-> " + fileTypes);
            log.info("File request sysEname-> " + sysEname);
            String uploadPath = uploadRoot + sysEname + "/";

            if (!StrUtil.isNull(uploadFolder)) {
                uploadPath += uploadFolder + "/";
            }
            uploadPath += nowDataStr;// 上传目录
            String fileSizeStr = getFileSize(fileSize);
            log.info("File name-> [" + fileName + "] | size[" + fileSizeStr + "]");

            //3、判断上传规则
            if (fileSize > fimaxLength) {
                resultMap.put("msg", "服务端暂不支持文件大小超过" + getFileSize(fimaxLength));
                log.error("File size-> 服务端暂不支持文件大小超过" + getFileSize(fimaxLength));
                JSONObject obj = JSONObject.fromObject(resultMap);
                this.outputJson(obj.toString(), response, "");
                return;
            }

            //4、执行上传
            log.info("File directory-> " + uploadPath);
            // 构建上传文件的存放路径，获取上传的文件名称，并结合存放路径，构建新的文件名称
            String filename = file.getOriginalFilename();
            File filepath = new File(uploadPath, filename);//创建新文件
            if (!filepath.getParentFile().exists()) { // 判断路径是否存在，不存在则新创建一个
                filepath.getParentFile().mkdirs();
            }
            //获取文件扩展名后缀
            String nameEx = (filename.lastIndexOf('.') >= 0) ? filename.substring(filename.lastIndexOf('.') + 1).toLowerCase() : "";
            String wrFileName = String.valueOf(System.currentTimeMillis()) + "." + nameEx;//指定文件新名
            String fileNewPath = uploadPath + File.separator + wrFileName;//新文件上传全路径
            String fileNewPathMin = uploadPath + File.separator +  String.valueOf(System.currentTimeMillis()) + "_min." + nameEx;//压缩图路径
            File fileNew = new File(fileNewPath);
            file.transferTo(fileNew);// 将上传文件保存到目标文件目录
            log.info("File is uploading path-> " + fileNewPath);

            //5、准备文件访问/下载地址内容及返回参数
            String downloadPath = downloadRoot + sysEname + File.separator;
            if (!StrUtil.isNull(uploadFolder)) {
                downloadPath += uploadFolder + File.separator;
            }
            downloadPath += nowDataStr + File.separator + wrFileName;
            downloadPath = downloadPath.replaceAll("\\\\", "/");
            log.info("File download full path-> " + downloadPath);

            resultMap.put("flag", "T");
            resultMap.put("msg", "上传成功");
            resultMap.put("murl", downloadPath);
            resultMap.put("filePath", uploadPath + File.separator);
            resultMap.put("fileNameNew", wrFileName);
            resultMap.put("fileName", fileName);
            resultMap.put("fileSize", fileSizeStr);
            resultMap.put("fileType", nameEx);
            resultMap.put("sysEname", sysEname);
            resultMap.put("ossFlag", ossFlag);

            long timeLong = (new Date().getTime() - starTime);
            resultMap.put("timeLong", timeLong + "ms");
            log.info("File upload result-->" + resultMap);
        }
        if (!ToolsUtil.isEmpty(resultMap)) {
            JSONObject obj = JSONObject.fromObject(resultMap);
            this.outputJson(obj.toString(), response, "");
        }
    }

    //发送短信
    @RequestMapping(value = "/sendSmsCode", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public void sendSmsCode(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> requestBody) throws Exception {
        ResultMsg msg = new ResultMsg("F", "短信发送失败");
        //Map<String, String> params = this.getParameterMap(request);
        Map<String, String> params = this.getParameterMapByJson(request, requestBody);
        log.info("client request params-->" + params);
        String type = params.get("type");
        String mobile = params.get("mobile");
        if (StrUtil.isNull(mobile)) {
            this.gotoErrorPage(request, response, "手机号码不能为空！");
            return;
        }
        if(!checkMobile(mobile)){
            this.gotoErrorPage(request, response, "手机号码格式有误！");
            return;
        }

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(params.get("frontSysCode"));//前端系统代码
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        if (result.get("errorCode").equals("F")){
            this.gotoErrorPage(request, response, result.get("errorMsg"));
            return;
        }

        String codeNo = UUIDUtil.getRandomStr("1", 6, 97);//验证码
        Map<String, String> resultSmsMap = CommonUtils.sendSmsByCache(mobile, codeNo);
        String resultCode = resultSmsMap.get("code");
        if ("OK".equals(resultCode)) {
            String content = "验证码已发送至您的手机上";
            if ("F".equals(resultSmsMap.get("sms_code_start"))) {
                content += "[" + codeNo + "]";
            }
            msg = new ResultMsg("T", content);
            CommonUtils.addCache("mobile_obj_" + mobile, codeNo, Integer.parseInt(StrUtil.doNull(CommonUtils.getConfigVal("expireTime")    ,"1200")));//5-6分钟
        }


        String userEmail = params.get("userEmail");
        if(StrUtil.isNotNull(userEmail)){
            log.info("-");
            log.info("准备发送邮件验证码："+userEmail);
//            Map<String, String> resultSmsMap2 = MailUtil.sendMail(userEmail,"","您的验证码为："+codeNo);
        }

        if (!ToolsUtil.isEmpty(msg)) {
            JSONObject obj = JSONObject.fromObject(msg);
            this.outputJson(obj.toString(), response, "");
        }
    }

    //验证手机号、邮箱等是否存在
    @RequestMapping(value = "/checkMobileOrEmailExist")
    @ResponseBody
    public void checkMobileOrEmailExist(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, String> params =this.getParameterMap(request);
        String source = StrUtil.doNull(params.get("source"), "");//登录来源：weixin,app

        log.info("client request params-->" + params);
        String userEmailMobile = params.get("userEmailMobile");
        if (StrUtil.isNull(userEmailMobile)) {
            this.gotoErrorPage(request, response, "参数不能为空！");
            return;
        }
        String randCode = params.get("randCode");
        if(StrUtil.isNotNull(randCode)){
            String randCodeVal = String.valueOf(request.getSession().getAttribute("randCode")) ;
            if(!randCodeVal.equals(randCode)){
                this.gotoErrorPage(request, response, "验证码有误！");
                return;
            }
        }
//        String userType = StrUtil.doNull(params.get("userType"),"safer");
        String sysEname = CommonUtils.getSysEname();
        StringBuffer sqls = new StringBuffer("");
        sqls.append("select * from uct_user u where u.sys_ename='"+sysEname+"' ");
        sqls.append(" and (u.email='"+userEmailMobile+"' or u.mobile='"+userEmailMobile+"'  or u.user_ename='"+userEmailMobile+"')");
        Object objs = IusPluginUtil.getInstance().select("plateform",sqls.toString(),0,0);
        if(objs!=null){
            List<DataMap> lists = (List<DataMap>)objs;
            if(lists.size()==1){
                DataMap userMap = (DataMap) lists.get(0);
                JSONObject obj = JSONObject.fromObject(userMap);
                obj.put("flag", "T");
                this.outputJson(obj.toString(), response, "");
                return;
            }else if(lists.size()>1){
                this.gotoErrorPage(request, response, "手机号或邮箱存在多个，请联系运营管理员！");
                return;
            }
        }
        this.gotoErrorPage(request, response, "手机号或邮箱不存在！");
        return;
    }


    //验证手机号是否存在
    @RequestMapping(value = "/checkMobileExist", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public void checkMobileExist(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> requestBody) throws Exception {
        ResultMsg msg = new ResultMsg("F", "注册失败");
        //Map<String, String> params = this.getParameterMap(request);
        Map<String, String> params = this.getParameterMapByJson(request, requestBody);
        String source = StrUtil.doNull(params.get("source"), "");//登录来源：weixin,app
        int userScore = 20;
        switch (source.toLowerCase()) {
            case "weixin":
                userScore = 20;
                break;
            case "app":
                userScore = 30;
                break;
        }

        log.info("client request params-->" + params);
        String mobile = params.get("mobile");
        if (StrUtil.isNull(mobile)) {
            this.gotoErrorPage(request, response, "手机号不能为空！");
            return;
        }
        Map<String, Object> whereMap = new HashMap<>();
        whereMap.put("uctUser.w_mobile", mobile);
//        whereMap.put("uctUser.w_userScore", userScore);
        ResultEntity resultEntity1 = IusPluginUtil.getInstance().select("plateform", "count", "s_uctUser", whereMap);
        Map<String, Object> resultMap = super.getResultEntityData(resultEntity1);
        if ("T".equals(resultMap.get("flag")) && Long.parseLong(String.valueOf(resultMap.get("result"))) > 0) {
            CommonUtils.removeCache("mobile_obj_" + mobile);//验证成功，移除
            this.gotoErrorPage(request, response, "手机号码已存在！");
            return;
        }
        msg = new ResultMsg("T", "验证成功，手机号不存在！");
        JSONObject obj = JSONObject.fromObject(msg);
        this.outputJson(obj.toString(), response, "");
    }


    //验证手机短信验证码
    @RequestMapping(value = "/checkSmsCode", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public void checkSmsCode(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> requestBody) throws Exception {
        ResultMsg msg = new ResultMsg("F", "注册失败");
        Map<String, String> params = this.getParameterMapByJson(request, requestBody);
        log.info("client request params-->" + params);
        String mobile = params.get("mobile");
        String smsCode = params.get("smsCode");//短信验证码
        if (StrUtil.isNull(mobile) || StrUtil.isNull(mobile)) {
            this.gotoErrorPage(request, response, "手机号或短信验证码不能为空！");
            return;
        }

        String smsCode_old = String.valueOf(CommonUtils.getCache("mobile_obj_" + mobile));
        log.info("smsCode validator -> [old->" + smsCode_old + "]=[input->" + smsCode + "]");
        if (!smsCode.equals(smsCode_old)) {
            this.gotoErrorPage(request, response, "短信验证码有误");
            return;
        } else {
            CommonUtils.removeCache("mobile_obj_" + mobile);//验证成功，移除
        }
        msg = new ResultMsg("T", "短信验证码验证成功！");
        JSONObject obj = JSONObject.fromObject(msg);
        this.outputJson(obj.toString(), response, "");
    }

    //根据userEname,或者手机号查询用户唯一编码
    @RequestMapping(value = "/checkedUser", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public Map<String, String> checkedUser(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> requestBody) throws Exception {
        Map<String, String> params = this.getParameterMapByJson(request, requestBody);
        log.info("client request params-->" + params);

        Map<String, String> map = new HashMap<String,String>();

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(params.get("frontSysCode"));//前端系统代码
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        log.info("查询前端系统结果["+result.toString()+"]");
        if (result.get("errorCode").equals("F")){
            map.put("flag",result.get("errorCode"));
            map.put("msg",result.get("errorMsg"));
            return map;
        }

        //先判断此用户是否已存在
        String mobile = StrUtil.doNull(params.get("mobile"), "");//手机号
        Map<String, Object> channelMap = new HashMap<>();
        channelMap.put("uctUser.w_mobile", mobile);
        ResultEntity resultEntity1 = IusPluginUtil.getInstance().select("plateform", "obj", "s_uctUser", channelMap);
        Map<String, Object> resultMap = super.getResultEntityData(resultEntity1);
        if ("T".equals(resultMap.get("flag")) && resultMap.get("result")!=null) {
            DataMap channelInfo = (DataMap) resultMap.get("result");
            String channel_userId = String.valueOf(channelInfo.get("userId"));
            String orgId = String.valueOf(channelInfo.get("orgId"));
            String userEname = String.valueOf(channelInfo.get("userEname"));
            log.info("已查找到该用户[userId="+channel_userId+"]");
            map.put("uctUser.userId",channel_userId);
            map.put("uctUser.orgId",orgId);
            map.put("uctUser.userEname",userEname);
            map.put("flag","T");
            map.put("msg","查询成功");
            return map;
        }else{
            map.put("msg","没有该用户");
            map.put("flag","F");
            return map;
        }
    }

    //app用户注册
    @RequestMapping(value = "/userRegisterForAPP", method = RequestMethod.POST, consumes = "application/json")
    @Transactional
    @ResponseBody
    public void userRegisterForAPP(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> requestBody) throws Exception {
        Map<String, String> params = this.getParameterMapByJson(request, requestBody);
        log.info("client request params-->" + params);

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(params.get("frontSysCode"));//前端系统代码
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        log.info("查询前端系统结果["+result.toString()+"]");
        if (result.get("errorCode").equals("F")){
            this.gotoErrorPage(request, response, result.get("errorMsg"));
            return;
        }

        String smsCode = params.get("uctUser.smsCode");//短信验证码
        String syncLogin = StrUtil.doNull(params.get("syncLogin"), "F");//是否同步登录
        String wUserId = StrUtil.doNull(params.get("uctUser.w_userId"), "");//区分是第一次注册新增，还是审核退回修改提交。
        String type = StrUtil.doNull(params.get("type"), "1");//1:默认用户名称+手机号+验证码方式，2：openId+微信昵称注册
        String mobile = StrUtil.doNull(params.get("uctUser.mobile"), "");//手机号
        String frontSysName = StrUtil.doNull(params.get("frontSysName"), "");//前端系统名称

        boolean isAdd = true;
        if (!StrUtil.isNull(wUserId)) {
            isAdd = false;
        }
        log.info("user register info is add -> " + isAdd);
        log.info("user register info is sync login -> " + syncLogin);
        String openId = StrUtil.doNull(params.get("uctUser.appUid"), "");//openId，当type=2时，必传
        String userCname = StrUtil.doNull(params.get("uctUser.userCname"), "匿名"+new Date().getTime());//nickName
        String userPass = StrUtil.doNull(params.get("uctUser.userPass"), "3b787f2d1c443062f3773af1071ccd65");//密码：默认123456
        String userType = StrUtil.doNull(params.get("uctUser.userType"), "broker");//用户类型：默认 broker=渠道商
        String def_userEname = "app_"+UUIDUtil.getRandomStr("3", 8, 97);//自动生成默认登录英文名称;
        String userEname = StrUtil.doNull(params.get("uctUser.userEname"), def_userEname);//默认userEname产生随机数
        if (isAdd) {
            Map<String, Object> whereMap = new HashMap<>();
            //判断类型，以备校验
            switch (type) {
                case "1"://用户名称+手机号+验证码方式
                    if (StrUtil.isNull(mobile) || StrUtil.isNull(smsCode)) {
                        this.gotoErrorPage(request, response, "手机号码或验证码不能为空");
                        return;
                    }
                    if(!checkMobile(mobile)){
                        this.gotoErrorPage(request, response, "手机号码格式有误！");
                        return;
                    }
                    String smsCode_old = String.valueOf(CommonUtils.getCache("mobile_obj_" + mobile));
                    log.info("smsCode validator -> [old->" + smsCode_old + "]=[input->" + smsCode + "]");
                    if (!smsCode.equals(smsCode_old)) {
                        this.gotoErrorPage(request, response, "短信验证码有误");
                        return;
                    } else {
                        CommonUtils.removeCache("mobile_obj_" + mobile);//验证成功，移除
                    }
//                    userEname = mobile;
                    whereMap.put("uctUser.w_mobile", mobile);
                    break;
                case "2"://openId+微信昵称注册
                    if (StrUtil.isNull(openId)) {
                        this.gotoErrorPage(request, response, "openId不能为空！");
                        return;
                    }
                    whereMap.put("uctUser.w_appUid", openId);
                    break;
                default:
                    whereMap.put("uctUser.w_userEname", userEname);
                    break;
            }
            log.info("userEname->"+userEname);
            log.info("userCname->"+userCname);
            ResultEntity resultEntity1 = IusPluginUtil.getInstance().select("plateform", "obj", "s_uctUser", whereMap);
            Map<String, Object> resultMap = super.getResultEntityData(resultEntity1);
            if ("T".equals(resultMap.get("flag")) && resultMap.get("result")!=null) {
                if("F".equals(syncLogin)){
                    switch (type) {
                        case "1"://用户名称+手机号+验证码方式
                            this.gotoErrorPage(request, response, "手机号已存在！");
                            return;
                        case "2"://openId+微信昵称注册
                            this.gotoErrorPage(request, response, "openId已存在！");
                            return;
                        default:
                            this.gotoErrorPage(request, response, "用户名已存在！");
                            break;
                    }
                }else{
                    log.info("openId["+openId+"]已存在.开始发起同步登录...");
                    DataMap userInfo = (DataMap) resultMap.get("result");
                    String login_userEname = String.valueOf(userInfo.get("userEname"));
                    //同步发起登录
                    //准备参数请求sso进行登录验证。
                    Map<String, Object> maps = new HashMap<String, Object>();
                    maps.put("isCheckPass", "F");//告知sso不验证密码
                    maps.put("userEname", login_userEname);
                    maps.put("Client-IP", StrUtil.doNull(params.get("Client-IP"), RequestTools.getIp(request)));
                    maps.put("userPass", userPass);
                    maps.put("sysEname", ToolsUtil.getInstance().getValueByKey("sysEname"));
                    maps.put("addressIP", maps.get("Client-IP"));
                    //请求sso返回登录结果
                    JSONObject resObj = getLoginJsonObject(request, response, maps);
                    this.outputJson(resObj.toString(), response, "");
                    return;
                }

            }
        } else {
            //注册修改
        }

        //准备数据
        Map<String, Object> paramsMap = new HashMap<String, Object>();
        paramsMap.putAll(params);
        String sysEname = CommonUtils.getSysEname();
//        String createTime = DateUtils.Now.fmt_yyyyMMdd_HHmmss();
        paramsMap.put("uctUser.userType", userType);
        paramsMap.put("uctUser.sysEname", sysEname);
        paramsMap.put("uctUser.delStatus", "0");//是否系统机构用户 0
        paramsMap.put("uctUser.userScore", StrUtil.doNull(params.get("uctUser.userScore"),"20"));//默认20
        paramsMap.put("uctUser.regSource", StrUtil.doNull( params.get("uctUser.regSource"),"app"));//默认weixin
        paramsMap.put("uctUser.userStatus", "1");//启用状态
        paramsMap.put("uctUser.userLevel", "2");//级别
        paramsMap.put("uctUser.userEname", userEname);
        paramsMap.put("uctUser.userTitle", StrUtil.doNull( params.get("uctUser.userTitle"),userCname));//默认等于userCname
        paramsMap.put("uctUser.userCname", userCname);
        paramsMap.put("uctUser.userPass", userPass);
        paramsMap.put("uctUser.frontSysCode", frontSysCode);
        paramsMap.put("uctUser.frontSysName", frontSysName);
        log.info("[" + userEname + "][" + userCname + "][" + mobile + "]开始注册【新增】操作...");
        //保存uctUser操作
        ResultEntity resultEntity = IusPluginUtil.getInstance().saveInvoke("plateform", "i_uctUser", paramsMap);
        Map<String, Object> resultMap = super.getResultEntityData(resultEntity);
        if ("F".equals(resultMap.get("flag"))) {
            this.gotoErrorPage(request, response, "操作失败！");
            return;
        }

        String userId = "";
        if (isAdd) {
            //注册新增
            Map<String, String> idsMap = (Map) resultMap.get("ids");
            userId = String.valueOf(idsMap.get("uctUser_userId"));
        }

        //注册成功后 创建该渠道商的二级渠道商  根据该前端系统所关联的一级渠道商查出该渠道商的ename
        String frontApplyBrokerCode= StrUtil.doNull(result.get("frontApplyBrokerCode"));//该用户的一级渠道商代码
        log.info("该一级渠道商[userId="+frontApplyBrokerCode+"]");
        Map<String, Object> firstBrokerMap = new HashMap<String,Object>();
        firstBrokerMap.put("ssApplyBroker.w_userId",frontApplyBrokerCode);
        firstBrokerMap.put("ssApplyBroker.userStatus","1");
        ResultEntity resultEntity1 = IusPluginUtil.getInstance().select("ssb", "obj", "s_ssApplyBroker", firstBrokerMap);
        Map<String, Object> firstBrokerMap1 = super.getResultEntityData(resultEntity1);
        if ("T".equals(firstBrokerMap1.get("flag")) && firstBrokerMap1.get("result")!=null) {
            log.info("会员关联渠道商，已查找到该渠道商[userId="+frontApplyBrokerCode+"]");
            DataMap channelInfo = (DataMap) firstBrokerMap1.get("result");
            Map<String, Object> upUserMap = new HashMap<String, Object>();
            upUserMap.put("uctUser.orgId", StrUtil.doNull( String.valueOf(channelInfo.get("userId")),"0"));
            upUserMap.put("uctUser.orgEname", StrUtil.doNull(String.valueOf(channelInfo.get("username")),"无"));
            upUserMap.put("uctUser.w_userId", userId);
            //补充uctUser中的orgID和orgEname
            ResultEntity resultEntity2 = IusPluginUtil.getInstance().saveInvoke("plateform", "u_uctUser", upUserMap);
            Map<String, Object> resultMap2 = super.getResultEntityData(resultEntity2);
            if ("F".equals(resultMap2.get("flag"))) {
                this.gotoErrorPage(request, response, "操作失败！");
                return;
            }
        }else{
            log.info("会员关联渠道商，未查找到该渠道商");
            this.gotoErrorPage(request, response, "该渠道商不存在！");
            return;
        }
        //准备该用户的渠道商数据
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramsMap.put("ssApplyBroker.applyLevel", "2");//级别
        paramsMap.put("ssApplyBroker.auditStatus", "90");//状态，自动为审核通过
        paramsMap.put("ssApplyBroker.auditRemark", "app自动创建该用户的渠道商信息");
        paramsMap.put("ssApplyBroker.delStatus", "F");
        paramsMap.put("ssApplyBroker.fatherId", frontApplyBrokerCode);//上级渠道商代码
        paramsMap.put("ssApplyBroker.sysName", sysEname);//上级渠道商代码
        paramsMap.put("ssApplyBroker.userEname", userEname);//用户账号
        paramsMap.put("ssApplyBroker.userCname", userCname);//用户名称
        paramsMap.put("ssApplyBroker.userId", userId);//用户ID
        paramsMap.put("ssApplyBroker.frontSysCode", frontSysCode);
        paramsMap.put("ssApplyBroker.createTime", DateUtils.Now.fmt_yyyyMMdd_HHmmss());
        paramsMap.put("ssApplyBroker.updateTime", DateUtils.Now.fmt_yyyyMMdd_HHmmss());

        log.info("[" + userEname + "][" + userCname + "][" + mobile + "]开始添加渠道商操作...");
        //保存uctUser操作
        ResultEntity resultBrokerEntity = IusPluginUtil.getInstance().saveInvoke("ssb", "i_ssApplyBroker", paramsMap);
        Map<String, Object> resultBrokerMap = super.getResultEntityData(resultBrokerEntity);
        if ("F".equals(resultBrokerMap.get("flag"))) {
            this.gotoErrorPage(request, response, "操作失败！");
            return;
        }

        //查询审核通过后挂到的渠道商下有哪些产品
        Map selectProMap = new HashMap();
        selectProMap.put("ssOrgProRelation.w_userId",frontApplyBrokerCode);
        ResultEntity selectProEntity = IusPluginUtil.getInstance().select("ssb", "list", "s_ssOrgProRelation", selectProMap);
        String proIds = "";
        if(!Validator.isEmpty(selectProEntity.getEntity())){
            List<DataMap> selectProList = (List)selectProEntity.getEntity();
            if(selectProList.size()>0){
                for (DataMap dataMap: selectProList) {
                    proIds += proIds==""?dataMap.get("proId"):"-#-"+dataMap.get("proId");
                }
                log.info("proIds----->>>>"+proIds);
                //建立产品和被平移的子级渠道商建立关系，同时默认分佣比例为10
                Map saveMap = new HashMap();
                saveMap.put("ifBatch","T");
                saveMap.put("ssOrgProRelation.splitAttr","proId");
                saveMap.put("ssOrgProRelation.userId",userId);
                saveMap.put("ssOrgProRelation.userOwner",userCname);
                saveMap.put("ssOrgProRelation.proId",proIds);
                saveMap.put("ssOrgProRelation.createTime", DateUtils.Now.fmt_yyyyMMdd_HHmmss());
                saveMap.put("ssOrgProRelation.bkgeRatio","10");
                saveMap.put("ssOrgProRelation.delStatus","F");
                ResultEntity resultOrgProEntity = IusPluginUtil.getInstance().saveInvoke("ssb", "ib_ssOrgProRelation", saveMap);
                log.info("resultEntity----->>>>>"+resultOrgProEntity.toString());
            }
        }

        Map<String, Object> resMap = new HashMap<String,Object>();
        resMap.put("flag", "T");
        resMap.put("userId", userId);
        resMap.put("userEname",userEname);
        resMap.put("userCname",userCname);
        resMap.put("mobile",mobile);
        resMap.put("msg", "注册成功");
        JSONObject obj = JSONObject.fromObject(resMap);
        log.info("操作执行结果：" + obj);
        if("T".equals(syncLogin)){
            log.info("注册成功.开始发起同步登录...");
            //同步发起登录
            //准备参数请求sso进行登录验证。
            Map<String, Object> maps = new HashMap<String, Object>();
            maps.put("isCheckPass", "F");//告知sso不验证密码
            maps.put("userEname", userEname);
            maps.put("Client-IP", StrUtil.doNull(params.get("Client-IP"), RequestTools.getIp(request)));
            maps.put("userPass", userPass);
            maps.put("sysEname", ToolsUtil.getInstance().getValueByKey("sysEname"));
            maps.put("addressIP", maps.get("Client-IP"));
            //请求sso返回登录结果
            JSONObject resObj = getLoginJsonObject(request, response, maps);
            this.outputJson(resObj.toString(), response, "");
        }else{
            this.outputJson(obj.toString(), response, "");
        }

    }

    //用户注册
    @RequestMapping(value = "/userRegister", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public void userRegister(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> requestBody) throws Exception {
        Map<String, String> params = this.getParameterMapByJson(request, requestBody);
        log.info("client request params-->" + params);

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(params.get("frontSysCode"));//前端系统代码
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        log.info("查询前端系统结果["+result.toString()+"]");
        if (result.get("errorCode").equals("F")){
            this.gotoErrorPage(request, response, result.get("errorMsg"));
            return;
        }

        String smsCode = params.get("uctUser.smsCode");//短信验证码
        String syncLogin = StrUtil.doNull(params.get("syncLogin"), "F");//是否同步登录
        String wUserId = StrUtil.doNull(params.get("uctUser.w_userId"), "");//区分是第一次注册新增，还是审核退回修改提交。
        String type = StrUtil.doNull(params.get("type"), "1");//1:默认用户名称+手机号+验证码方式，2：openId+微信昵称注册
        String mobile = StrUtil.doNull(params.get("uctUser.mobile"), "");//手机号
        String frontSysName = StrUtil.doNull(params.get("frontSysName"), "");//前端系统名称
        String channelNo= StrUtil.doNull(params.get("channelNo"), "");//渠道商登录账号
        boolean isAdd = true;
        if (!StrUtil.isNull(wUserId)) {
            isAdd = false;
        }
        log.info("user register info is add -> " + isAdd);
        log.info("user register info is sync login -> " + syncLogin);
        String openId = StrUtil.doNull(params.get("uctUser.appUid"), "");//openId，当type=2时，必传
        String userCname = StrUtil.doNull(params.get("uctUser.userCname"), "匿名"+new Date().getTime());//nickName
        String userPass = StrUtil.doNull(params.get("uctUser.userPass"), "3b787f2d1c443062f3773af1071ccd65");//密码：默认123456
        String userType = StrUtil.doNull(params.get("uctUser.userType"), "member");//用户类型：默认member=会员
        String def_userEname = "wx_"+UUIDUtil.getRandomStr("3", 8, 97);//自动生成默认登录英文名称;
        String userEname = StrUtil.doNull(params.get("uctUser.userEname"), def_userEname);//默认userEname产生随机数
        if (isAdd) {
            //注册新增
            if(!StrUtil.isNull(channelNo)){
                //特殊处理，关联渠道商账号
                Map<String, Object> channelMap = new HashMap<>();
                channelMap.put("uctUser.wo_userEname", channelNo);
                channelMap.put("uctUser.wo_mobile", channelNo);
                log.info("会员关联渠道商，开始查找渠道商["+channelNo+"]");
                ResultEntity resultEntity1 = IusPluginUtil.getInstance().select("plateform", "obj", "s_uctUser", channelMap);
                Map<String, Object> resultMap = super.getResultEntityData(resultEntity1);
                if ("T".equals(resultMap.get("flag")) && resultMap.get("result")!=null) {
                    DataMap channelInfo = (DataMap) resultMap.get("result");
                    String channel_userId = String.valueOf(channelInfo.get("userId"));
                    String channel_userCname = String.valueOf(channelInfo.get("userCname"));
                    String channel_userTitle = String.valueOf(channelInfo.get("userTitle"));
                    log.info("会员关联渠道商，已查找到该渠道商[userId="+channel_userId+"][userCname="+channel_userCname+"][userTitle="+channel_userTitle+"]");
                    params.put("uctUser.orgId",channel_userId);
                    params.put("uctUser.orgEname",channel_userCname);
                }else{
                    log.info("会员关联渠道商，未查找到该渠道商");
                    this.gotoErrorPage(request, response, "该渠道商不存在！");
                    return;
                }
            }
            Map<String, Object> whereMap = new HashMap<>();
            //判断类型，以备校验
            switch (type) {
                case "1"://用户名称+手机号+验证码方式
                    if (StrUtil.isNull(mobile) || StrUtil.isNull(smsCode)) {
                        this.gotoErrorPage(request, response, "手机号码或验证码不能为空");
                        return;
                    }
                    if(!checkMobile(mobile)){
                        this.gotoErrorPage(request, response, "手机号码格式有误！");
                        return;
                    }
                    String smsCode_old = String.valueOf(CommonUtils.getCache("mobile_obj_" + mobile));
                    log.info("smsCode validator -> [old->" + smsCode_old + "]=[input->" + smsCode + "]");
                    if (!smsCode.equals(smsCode_old)) {
                        this.gotoErrorPage(request, response, "短信验证码有误");
                        return;
                    } else {
                        CommonUtils.removeCache("mobile_obj_" + mobile);//验证成功，移除
                    }
//                    userEname = mobile;
                    whereMap.put("uctUser.w_mobile", mobile);
                    break;
                case "2"://openId+微信昵称注册
                    if (StrUtil.isNull(openId)) {
                        this.gotoErrorPage(request, response, "openId不能为空！");
                        return;
                    }
                    whereMap.put("uctUser.w_appUid", openId);
                    break;
                default:
                    whereMap.put("uctUser.w_userEname", userEname);
                   break;
            }
            log.info("userEname->"+userEname);
            log.info("userCname->"+userCname);
            ResultEntity resultEntity1 = IusPluginUtil.getInstance().select("plateform", "obj", "s_uctUser", whereMap);
            Map<String, Object> resultMap = super.getResultEntityData(resultEntity1);
            if ("T".equals(resultMap.get("flag")) && resultMap.get("result")!=null) {
                if("F".equals(syncLogin)){
                    switch (type) {
                        case "1"://用户名称+手机号+验证码方式
                            this.gotoErrorPage(request, response, "手机号已存在！");
                            return;
                        case "2"://openId+微信昵称注册
                            this.gotoErrorPage(request, response, "openId已存在！");
                            return;
                        default:
                            this.gotoErrorPage(request, response, "用户名已存在！");
                            break;
                    }
                }else{
                    log.info("openId["+openId+"]已存在.开始发起同步登录...");
                    DataMap userInfo = (DataMap) resultMap.get("result");
                    String login_userEname = String.valueOf(userInfo.get("userEname"));
                    //同步发起登录
                    //准备参数请求sso进行登录验证。
                    Map<String, Object> maps = new HashMap<String, Object>();
                    maps.put("isCheckPass", "F");//告知sso不验证密码
                    maps.put("userEname", login_userEname);
                    maps.put("Client-IP", StrUtil.doNull(params.get("Client-IP"), RequestTools.getIp(request)));
                    maps.put("userPass", userPass);
                    maps.put("sysEname", ToolsUtil.getInstance().getValueByKey("sysEname"));
                    maps.put("addressIP", maps.get("Client-IP"));
                    //请求sso返回登录结果
                    JSONObject resObj = getLoginJsonObject(request, response, maps);
                    this.outputJson(resObj.toString(), response, "");
                    return;
                }

            }
        } else {
            //注册修改
        }

        //准备数据
        Map<String, Object> paramsMap = new HashMap<String, Object>();
        paramsMap.putAll(params);
        String sysEname = CommonUtils.getSysEname();
//        String createTime = DateUtils.Now.fmt_yyyyMMdd_HHmmss();
        paramsMap.put("uctUser.userType", userType);
        paramsMap.put("uctUser.sysEname", sysEname);
        paramsMap.put("uctUser.delStatus", "0");//是否系统机构用户 0
        paramsMap.put("uctUser.userScore", StrUtil.doNull(params.get("uctUser.userScore"),"20"));//默认20
        paramsMap.put("uctUser.regSource", StrUtil.doNull( params.get("uctUser.regSource"),"weixin"));//默认weixin
        paramsMap.put("uctUser.userStatus", "1");//启用状态
        paramsMap.put("uctUser.userEname", userEname);
        paramsMap.put("uctUser.orgId", StrUtil.doNull( params.get("uctUser.orgId"),"0"));
        paramsMap.put("uctUser.orgEname", StrUtil.doNull( params.get("uctUser.orgEname"),"无"));
        paramsMap.put("uctUser.userTitle", StrUtil.doNull( params.get("uctUser.userTitle"),userCname));//默认等于userCname
        paramsMap.put("uctUser.userCname", userCname);
        paramsMap.put("uctUser.userPass", userPass);
        paramsMap.put("uctUser.frontSysCode", frontSysCode);
        paramsMap.put("uctUser.frontSysName", frontSysName);
        log.info("[" + userEname + "][" + userCname + "][" + mobile + "]开始注册【新增】操作...");
        //保存uctUser操作
        ResultEntity resultEntity = IusPluginUtil.getInstance().saveInvoke("plateform", "i_uctUser", paramsMap);
        Map<String, Object> resultMap = super.getResultEntityData(resultEntity);
        if ("F".equals(resultMap.get("flag"))) {
            this.gotoErrorPage(request, response, "操作失败！");
            return;
        }
        String userId = "";
        if (isAdd) {
            //注册新增
            Map<String, String> idsMap = (Map) resultMap.get("ids");
            userId = String.valueOf(idsMap.get("uctUser_userId"));
        }
        Map<String, Object> resMap = new HashMap<String,Object>();
        resMap.put("flag", "T");
        resMap.put("userId", userId);
        resMap.put("userEname",userEname);
        resMap.put("userCname",userCname);
        resMap.put("mobile",mobile);
        resMap.put("msg", "注册成功");
        JSONObject obj = JSONObject.fromObject(resMap);
        log.info("操作执行结果：" + obj);
        if("T".equals(syncLogin)){
            log.info("注册成功.开始发起同步登录...");
            //同步发起登录
            //准备参数请求sso进行登录验证。
            Map<String, Object> maps = new HashMap<String, Object>();
            maps.put("isCheckPass", "F");//告知sso不验证密码
            maps.put("userEname", userEname);
            maps.put("Client-IP", StrUtil.doNull(params.get("Client-IP"), RequestTools.getIp(request)));
            maps.put("userPass", userPass);
            maps.put("sysEname", ToolsUtil.getInstance().getValueByKey("sysEname"));
            maps.put("addressIP", maps.get("Client-IP"));
            //请求sso返回登录结果
            JSONObject resObj = getLoginJsonObject(request, response, maps);
            this.outputJson(resObj.toString(), response, "");
        }else{
            this.outputJson(obj.toString(), response, "");
        }
    }

    /**
     * 密码找回、密码修改
     * type=1:密码找回，2：密码修改
     */
    @RequestMapping(value = "/userPass", method = RequestMethod.POST, consumes = "application/json")
    @ResponseBody
    public void userPass(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> requestBody) throws Exception {
        ResultMsg msg = new ResultMsg("F", "注册失败");
        //Map<String, String> params = this.getParameterMap(request);
        Map<String, String> params = this.getParameterMapByJson(request, requestBody);
        log.info("client request params-->" + params);

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(params.get("frontSysCode"));//前端系统代码
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        if (result.get("errorCode").equals("F")){
            this.gotoErrorPage(request, response, result.get("errorMsg"));
            return;
        }

        String smsCode = params.get("smsCode");//短信验证码
        String mobile = params.get("mobile");
        String oldPass = params.get("oldPass");
        String newPass = params.get("newPass");
        String openId = params.get("openId");
        String source = params.get("source");//来源
        String type = params.get("type");//根据手机号= 1:密码找回，2：密码修改
        switch (type) {
            case "1":
                if (StrUtil.isNull(mobile) || StrUtil.isNull(newPass) || StrUtil.isNull(smsCode)) {
                    this.gotoErrorPage(request, response, "必填项不能为空！");
                    return;
                }
                if ("weixin".equals(source.toLowerCase())) {
                    if (StrUtil.isNull(openId)) {
                        this.gotoErrorPage(request, response, "缺少openId参数！");
                        return;
                    }
                }
                break;
            case "2":
                if (StrUtil.isNull(mobile) || StrUtil.isNull(newPass) || StrUtil.isNull(oldPass)) {
                    this.gotoErrorPage(request, response, "必填项不能为空！");
                    return;
                }
                break;
        }
        int userScore = 20;
        switch (source.toLowerCase()) {
            case "weixin":
                userScore = 20;
                break;
            case "app":
                userScore = 30;
                break;
        }

        Map<String, Object> whereMap = new HashMap<>();
        whereMap.put("uctUser.w_mobile", mobile);
        whereMap.put("uctUser.w_userScore", userScore);
        ResultEntity resultEntity1 = IusPluginUtil.getInstance().select("plateform", "obj", "s_uctUser", whereMap);
        Map<String, Object> resultMap = super.getResultEntityData(resultEntity1);
        if ("F".equals(resultMap.get("flag")) && StrUtil.isNull(String.valueOf(resultMap.get("result")))) {
            CommonUtils.removeCache("mobile_obj_" + mobile);//验证成功，移除
            this.gotoErrorPage(request, response, "手机号不已存在！");
            return;
        }
        DataMap userInfo = (DataMap) resultMap.get("result");
        if ("weixin".equals(source) && !StrUtil.isNull(openId)) {
            String appUid = String.valueOf(userInfo.get("appUid"));
            if (!openId.equals(appUid)) {
                log.info("手机号[" + mobile + "]和该微信用户不匹配-[openId=" + openId + "]-[appUid=" + appUid + "]");
                this.gotoErrorPage(request, response, "手机号和该微信用户不匹配！");
                return;
            }
        }
        String userCname = String.valueOf(userInfo.get("userCname"));
        String userId = String.valueOf(userInfo.get("userId"));
        switch (type) {
            case "1":
                //密码找回时，需要验证短信验证码
                String smsCode_old = String.valueOf(CommonUtils.getCache("mobile_obj_" + mobile));
                log.info("smsCode validator -> [old->" + smsCode_old + "]=[input->" + smsCode + "]");
                if (!smsCode.equals(smsCode_old)) {
                    this.gotoErrorPage(request, response, "短信验证码有误");
                    return;
                } else {
                    CommonUtils.removeCache("mobile_obj_" + mobile);//验证成功，移除
                }
                break;
            case "2":
                //密码修改时，判断输入的旧密码必须=存的密码；
                if (!oldPass.equals(String.valueOf(userInfo.get("userPass")))) {
                    this.gotoErrorPage(request, response, "原密码输入有误！");
                    return;
                }
                break;
        }

        //准备数据
        Map<String, Object> paramsMap = new HashMap<String, Object>();
        log.info("开始修改用户密码[" + userCname + "]...");
        paramsMap.put("uctUser.w_userId", userId);
        paramsMap.put("uctUser.userPass", newPass);

        //保存操作
        ResultEntity resultEntity = IusPluginUtil.getInstance().saveInvoke("plateform", "u_uctUser", paramsMap);
        resultMap = super.getResultEntityData(resultEntity);
        log.info("执行结果：" + resultMap);
        if ("F".equals(resultMap.get("flag"))) {
            this.gotoErrorPage(request, response, "操作失败！");
            return;
        }
        resultMap.put("msg", "密码修改成功");
        JSONObject obj = JSONObject.fromObject(resultMap);
        this.outputJson(obj.toString(), response, "");
    }

    @Autowired(required = false)
    @Qualifier("ssbService")
    private ApiService ssbService;//注入本工程bean

    //初始化方法
    @ModelAttribute
    public void populateModel() throws Exception {
        if (this.iusService == null) {
            this.setIusService(ssbService);//注入本工程bean
        }
        if (!AnnotationUtil.isScanning) {
            AnnotationUtil.getInstance().loadCalssBean("com.apache.ius");
        }
    }
    private static String getFileSize(long leng) {
        String re = String.valueOf(leng);
        if (leng >= (1024 * 1024 * 1024)) {
            re = NumberUtils.divide(leng, (1024 * 1024 * 1024), 0) + "G";
        } else if (leng >= (1024 * 1024)) {
            re = NumberUtils.divide(leng, (1024 * 1024), 0) + "M";
        } else if (leng >= (1024)) {
            re = NumberUtils.divide(leng, (1024), 0) + "KB";
        } else {
            re = leng + "";
        }
        return re;
    }

    /**
     * 服务器时间戳
     * @param request
     * @return
     */
    @RequestMapping(value = "/time", method = { RequestMethod.GET})
    @ResponseBody
    public Object getTime(HttpServletRequest request) throws IOException{
        Map<String, String> params = this.getParameterMap(request);
        log.info("getTime.request->"+params);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("flag","T");
        resultMap.put("dataTimeLong",DateUtils.Now.toLong());
        resultMap.put("dataTimeStr",DateUtils.Now.fmt_yyyyMMdd_HHmmss());
        String afterDate = DateUtils.format(DateUtils.afterNDays(1), DateUtils.FmtStr.yyyyMMdd.toString())+" 00:00:00";
        resultMap.put("dataAfterStr",afterDate);//明天凌晨
        return resultMap;
    }

    /**
     * 请求code2Session接口拿到用的openid和session_key,openid是用户在微信中唯一标识，我们就可以把这个
     * @return
     */
    @RequestMapping(value = "/wechatCode2Session", method = { RequestMethod.GET})
    @ResponseBody
    public Object wechatCode2Session(@RequestParam String code,@RequestParam String frontSysCodes, HttpServletResponse response) throws IOException{

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(frontSysCodes);
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        if (result.get("errorCode").equals("F")){
            throw new BusinessException("此系统有误：" + result.get("errorMsg"));
        }

        Map<String, Object> resultMap = new HashMap<>();
        log.info("根据code获取微信openId开始 start...");
        resultMap.put("flag","F");

        //查询配置【小程序】【启用状态】唯一数据，获取相应appId和appSecret
        Map<String,Object> appConfig_xcx = (Map<String,Object>)CommonUtils.getCacheByAppConfig("wechat_xcx");
        if(appConfig_xcx==null){
            resultMap.put("msg","服务端未找到微信小程序的配置信息，请联系平台管理员！");
            return resultMap;
        }
        Map<String,String> mapName = (Map<String,String>)appConfig_xcx.get("wechat_xcx_name");
        Map<String,String> mapSecret = (Map<String,String>)appConfig_xcx.get("wechat_xcx_appSecret");
        Map<String,String> mapAppId = (Map<String,String>)appConfig_xcx.get("wechat_xcx_appId");
        String appName = String.valueOf(mapName.get("appValue"));
        String appId = String.valueOf(mapAppId.get("appValue"));
        String appSecret = String.valueOf(mapSecret.get("appValue"));
        log.info("wechat_xcx_name->"+appName);
        log.info("wechat_xcx_appId->"+appId);
        log.info("wechat_xcx_appSecret->"+appSecret);

        //2、根据code获取openid和session_key
        Map<String,String> httpMap = new HashMap<>();
        httpMap.put("appid",appId);
        httpMap.put("secret", appSecret);
        httpMap.put("js_code", code);
        httpMap.put("grant_type", "authorization_code");
        Map<String,String> heads = new HashMap<>();
        heads.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        String host="https://api.weixin.qq.com/sns/jscode2session";
        log.info("wechatCode2Session.url->"+host);
        log.info("wechatCode2Session.param->"+httpMap);
        try {
            HttpResponse responseData = HttpUtils.doGet(host, null, "get", heads, httpMap);
            String resStr = EntityUtils.toString(responseData.getEntity());
            log.info("wechatCode2Session.res->"+resStr);
            JSONObject jsonObject = JSONObject.fromObject(resStr);
            if(jsonObject!=null&&!jsonObject.containsKey("openid")) {
                resultMap.put("msg","返回参数错误："+String.valueOf(jsonObject.get("errcode")));
                return resultMap;
            }
            String openid = (String)jsonObject.get("openid");
            String sessionKey = (String)jsonObject.get("session_key");

            //{"session_key":"H4sziX8IjLGdHoTaxDZYeg==","openid":"oHlv943T2k2gxwGTWuNsf3lHeeDw"}
            resultMap.put("flag","T");
            resultMap.put("openId",openid);
            resultMap.put("dateTime",DateUtils.Now.fmt_yyyyMMdd_HHmmss());
            log.info("根据code获取微信openId成功，返回结果->"+resultMap);
//            resultMap.put("sessionKey",sessionKey);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("msg","服务端调用微信平台出错："+e.getMessage());
            return resultMap;
        }
    }

    /**
     * 请求wechatToken接口获取小程序的access_token，存储到缓存
     * @return
     */
    @RequestMapping(value = "/wechatToken", method = { RequestMethod.GET})
    @ResponseBody
    public Object wechatToken(HttpServletResponse response) throws IOException{
        return getWeiXinAccessToken();
    }

    //获取微信access_token
    private Map<String, Object> getWeiXinAccessToken(){
        Map<String, Object> resultMap = new HashMap<>();
        log.info("根据code获取微信access_token开始 start...");
        resultMap.put("flag","F");

        //查询配置【小程序】【启用状态】唯一数据，获取相应appId和appSecret
        Map<String,Object> appConfig_xcx = (Map<String,Object>)CommonUtils.getCacheByAppConfig("wechat_xcx");
        if(appConfig_xcx==null){
            resultMap.put("msg","服务端未找到微信小程序的配置信息，请联系平台管理员！");
            return resultMap;
        }
        Map<String,String> mapName = (Map<String,String>)appConfig_xcx.get("wechat_xcx_name");
        Map<String,String> mapSecret = (Map<String,String>)appConfig_xcx.get("wechat_xcx_appSecret");
        Map<String,String> mapAppId = (Map<String,String>)appConfig_xcx.get("wechat_xcx_appId");
        String appName = String.valueOf(mapName.get("appValue"));
        String appId = String.valueOf(mapAppId.get("appValue"));
        String appSecret = String.valueOf(mapSecret.get("appValue"));
        log.info("wechat_xcx_name->"+appName);
        log.info("wechat_xcx_appId->"+appId);
        log.info("wechat_xcx_appSecret->"+appSecret);

        Map<String,String> httpMap = new HashMap<>();
        httpMap.put("appid",appId);
        httpMap.put("secret", appSecret);
        httpMap.put("grant_type", "client_credential");
        Map<String,String> heads = new HashMap<>();
        heads.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        String host="https://api.weixin.qq.com/cgi-bin/token";
        log.info("wechatToken.url->"+host);
        log.info("wechatToken.param->"+httpMap);

        try {
            HttpResponse responseData = HttpUtils.doGet(host, null, "get", heads, httpMap);
            String resStr = EntityUtils.toString(responseData.getEntity());
            log.info("wechatToken.res->"+resStr);
            JSONObject jsonObject = JSONObject.fromObject(resStr);
            if(jsonObject!=null&&!jsonObject.containsKey("access_token")) {
                resultMap.put("msg","返回参数错误："+String.valueOf(jsonObject.get("errcode"))+"|"+String.valueOf(jsonObject.get("errmsg")));
                return resultMap;
            }
            String access_token = (String)jsonObject.get("access_token");
            log.info("wechatToken.access_token->"+access_token);
            CommonUtils.addCache("wechat_access_token", access_token, 7200);//2小时

            resultMap.put("flag","T");
            resultMap.put("access_token",access_token);
            resultMap.put("dateTime",DateUtils.Now.fmt_yyyyMMdd_HHmmss());
            log.info("根据code获取微信access_token成功，返回结果->"+resultMap);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("msg","服务端调用微信平台出错："+e.getMessage());
            return resultMap;
        }
    }

    /**
     * 请求getwxacodeunlimit接口获取小程序的二维码
     * @return
     */
    @RequestMapping(value = "/wechatXcxQrcode", method = { RequestMethod.GET})
    @ResponseBody
    public Object wechatXcxQrcode(HttpServletRequest request,HttpServletResponse response) throws IOException{
        Map<String, String> params = this.getParameterMap(request);
        log.info("params->"+params);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("flag","F");

        String channelId = params.get("channelId");
        String channelName = params.get("channelName");
        String fileUploadDirectory = ToolsUtil.getInstance().getLocalByKey("config.properties", "UPLOAD_DIRECTORY");//获取文件需要上传到的根目录
        String fileDownloadUrl = ToolsUtil.getInstance().getLocalByKey("config.properties", "DOWNLOAD_URL");//获取文件需要下载的根目录地址
        String uploadRoot = fileUploadDirectory + "/atta/"; //获取文件需要上传到的根目录
        String downloadRoot = fileDownloadUrl + "/atta/";//获取文件需要下载的根目录
        String sysEname = CommonUtils.getSysEname();
        String uploadPath = uploadRoot + sysEname + "/";
        String dirName = "qrcode";
        uploadPath += dirName;// 上传目录
        String filename = channelName+"-"+channelId+".png";
        File filepath = new File(uploadPath, filename);//创建新文件
        if (!filepath.getParentFile().exists()) { // 判断路径是否存在，不存在则新创建一个
            filepath.getParentFile().mkdirs();
        }
//        String fileNewPath = uploadPath + File.separator + filename;//新文件上传全路径
        //5、准备文件访问/下载地址内容及返回参数
        String downloadPath = downloadRoot + sysEname + File.separator;
        downloadPath += dirName + File.separator + filename;
        downloadPath = downloadPath.replaceAll("\\\\", "/");
        if(filepath.exists()){
            resultMap.put("flag","T");
            resultMap.put("msg","二维码文件已存在");
            resultMap.put("downloadPath",downloadPath);
            resultMap.put("fileName",filepath.getName());
            log.info("二维码文件已存在,无需重新请求微信服务器生成二维码图片！！");
            log.info("res->"+resultMap.toString());
            return resultMap;
        }
        log.info("根据access_token小程序码二维码开始 start...");

        String access_token = String.valueOf(CommonUtils.getCache("wechat_access_token"));
        if(StrUtil.isNull(access_token)){
            Map<String, Object> restMap = getWeiXinAccessToken();
            if("F".equals(String.valueOf(restMap.get("flag")))){
                resultMap.put("flag","F");
                resultMap.put("msg","获取微信access_token失败，请稍后再试！");
                log.info("获取微信access_token失败，请稍后再试！");
                return resultMap;
            }
            access_token = String.valueOf(CommonUtils.getCache("wechat_access_token"));
        }

//        String sceneStr="qdsid=123&qdsname="+new String(Base64Utils.encode("中".getBytes("UTF-8")));
        String sceneStr="qdsid="+channelId;

        String host="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token;
        log.info("qrcode.url->"+host);
        log.info("scene.param->"+sceneStr);
        log.info("scene.length->"+sceneStr.length());

        RestTemplate rest = new RestTemplate();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            Map<String,Object> param = new HashMap<>();
            param.put("page", "pages/indexPage/indexPage");
            param.put("scene", sceneStr);
            log.info("req->" + param);

            MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
            HttpEntity requestEntity = new HttpEntity(param, headers);
            ResponseEntity<byte[]> entity = rest.exchange(host, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            byte[] result = entity.getBody();
            String resStr = IOUtils.toString(result,"UTF-8");
            if(resStr.indexOf("errcode")>-1){
                JSONObject jsonObject = JSONObject.fromObject(resStr);
                if(jsonObject!=null&&jsonObject.containsKey("errcode")) {
                    log.info("res->" + jsonObject.toString());
                    resultMap.put("msg","二维码生成失败，参数或格式有误！");
                    return resultMap;
                }
            }

            inputStream = new ByteArrayInputStream(result);

            if (!filepath.exists()){
                filepath.createNewFile();
            }
            outputStream = new FileOutputStream(filepath);
            int len = 0;
            byte[] buf = new byte[1024];
            while ((len = inputStream.read(buf, 0, 1024)) != -1) {
                outputStream.write(buf, 0, len);
            }
            outputStream.flush();

            resultMap.put("flag","T");
            resultMap.put("msg","二维码生成成功");
            resultMap.put("downloadPath",downloadPath);
            resultMap.put("fileName",filepath.getName());
            log.info("res->"+resultMap.toString());
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("msg","服务端调用微信平台出错："+e.getMessage());
            return resultMap;
        }finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @RequestMapping("/download")
    public void download(HttpServletRequest request,HttpServletResponse response) throws IOException {
        Map<String, String> params = this.getParameterMap(request);
        log.info("params->"+params);
        String fileName = params.get("fileName");
        log.info("download.fileName is->"+fileName);
        if (StrUtil.isNull(fileName)) {
            return;
        }

        String fileUploadDirectory = ToolsUtil.getInstance().getLocalByKey("config.properties", "UPLOAD_DIRECTORY");//获取文件需要上传到的根目录
        String fileDownloadUrl = ToolsUtil.getInstance().getLocalByKey("config.properties", "DOWNLOAD_URL");//获取文件需要下载的根目录地址
        String uploadRoot = fileUploadDirectory + "/atta/"; //获取文件需要上传到的根目录
        String downloadRoot = fileDownloadUrl + "/atta/";//获取文件需要下载的根目录
        String sysEname = CommonUtils.getSysEname();
        String uploadPath = uploadRoot + sysEname + "/";
        String dirName = "qrcode";
        uploadPath += dirName+"/"+fileName;// 文件目录

        response.setContentType("multipart/form-data");
        //2.设置文件头
        String userAgent = request.getHeader("User-Agent");
        if (!StrUtil.isNull(userAgent)) {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } else {
            if (userAgent.indexOf("MSIE") != -1) {
                // IE使用URLEncoder
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {
                // FireFox使用ISO-8859-1
                fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            }
        }
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
        response.setHeader("Pragma", "public");
        response.setDateHeader("Expires", (System.currentTimeMillis() + 1000));
        File file = new File(uploadPath);
        OutputStream out = null;
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            out = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int count = 0;
            while ((count = inputStream.read(buffer)) != -1) {
                out.write(buffer, 0, count);
            }
            out.close();
            out.flush();
        } catch (IOException e) {
            log.error("文件下载异常->"+e.getMessage());
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    /**
     * @Description 保单生成通知接口
     * http://121.89.168.7:81/ssb/api/callback/notice
     * {
     *     "jsondata": {
     *         "operateType": "2",
     *         "policyNo": "66201881133201800011000012",
     *         "proposalNo": "06201881133201800011000020",
     *         "status": "3"
     *     }
     * }
     */
    @RequestMapping(value = "/callback/notice", method = { RequestMethod.POST})
    @ResponseBody
    public Object callbackNotice(HttpServletRequest request) {
        JSONObject data = new JSONObject();
        data.put("success", "false");
        try {
            String msg = IOUtils.toString(request.getInputStream(),"UTF-8");
            log.info("callbackNotice 请求参数->"+msg);
            if(StrUtil.isNotNull(msg)) {
                String str = AESUtil.decrypt(msg,"ABQDKEY");
                JSONObject json = JSONObject.fromObject(str);
                Map map = new HashMap();
                map.putAll(json.getJSONObject("jsondata"));
                CustomMethodPlugin plugin = (CustomMethodPlugin)SpringContextLoader.getBean("hhePolicyMessage");
                plugin.beforeInvoke(map);
                Map result = (Map)map.get("resultData");
                if(null != result){
                    data.putAll(result);
                }else{
                    data.put("msg", "操作失败");
                }
            } else {
                data.put("msg", "缺少参数");
            }
        } catch (Exception e) {
            data.put("msg", "操作失败");
        }
        return AESUtil.encrypt(data.toString(),"ABQDKEY");
    }

    /**
     * 获取黄河指定类型信息的方法
     * @param request
     * @param infoType 待获取信息类型
     * @return
     */
    @RequestMapping(value = "/search/{infoType}", method = { RequestMethod.POST})
    @ResponseBody
    public Object selectInfo(HttpServletRequest request,HttpServletResponse response,@PathVariable String infoType){
        Map data = new HashMap();
        JSONObject head = new JSONObject();
        head.put("errorCode", "0001");
        head.put("timeStamp", DateUtils.Now.fmt_yyyyMMdd_HHmmss());
        Object obj = SpringContextLoader.getBean(infoType);
        if(null == obj){
            head.put("errorMsg", "数据接口不存在");
            data.put("head",head);
           return data;
        }
        CustomMethodPlugin plugin = (CustomMethodPlugin)obj;
        try {
            String reqMsg = IOUtils.toString(request.getInputStream(),"UTF-8");
            log.info(infoType+" 请求参数->"+reqMsg);
            Object result = null;
            Map plyData = null;
            if(StrUtil.isNotNull(reqMsg)) {
                JSONObject json = JSONObject.fromObject(reqMsg);
                Map map = new HashMap();
                map.putAll(json);
                plyData = (Map)plugin.beforeInvoke(map);
                result = map.get("resultData");
            } else {
               Map reqData = getParameterMap(request);
                plyData = (Map)plugin.beforeInvoke(reqData);
                result = reqData.get("resultData");
            }
            if("hheInsurancePolicy".equalsIgnoreCase(infoType)){//投单接口
                if(null == plyData){
                    head.put("errorMsg", "投保失败请重试");
                    data.put("head",head);
                    data.put("body",result);
                    return data;
                }
                plyData.put("resultType", "processSql");
                plyData = AdapterFactory.getInstance().getReqParamForBefor("setReqParam", plyData, request, response);//前拦截
                String execptionMsg = String.valueOf(plyData.get("execptionMsg"));
                String errorMsg = StrUtil.doNull(String.valueOf(plyData.get("errorMsg")),"");
                if (StrUtil.isNotNull(execptionMsg)) {
                    head.put("errorMsg", execptionMsg);
                    head.put("errorMsgReal",errorMsg);
                    data.put("head",head);
                    return data;
                }
                ParamsVo vo = new ParamsVo();
                vo.setParams(plyData);
                vo.setMethodKey("dymicSql");
                ResultEntity entity = doIusService(vo);
                Map<String, Object> resData = super.getResultEntityData(entity);
                if (ToolsUtil.isEmpty(resData) || "F".equals(String.valueOf(resData.get("flag")))) {
                    if (ToolsUtil.isEmpty(resData)){
                        head.put("errorMsg", "投保失败请重试");
                        data.put("head",head);
                    }else{
                        head.put("errorMsg", resData.get("msg"));
                    }
                    data.put("head",head);
                    return data;
                } else {
                    Map plyMap = (Map)result;
                    plyMap.put("entity",entity.getEntity());
                    return plyMap;
                }
            }
            if(result==null){
                head.put("errorMsg", "操作失败");
                data.put("head",head);
                return data;
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }catch (BusinessException e){
            head.put("errorMsg", e.getMessage());
        }
        head.put("errorMsg", "操作失败");
        data.put("head",head);
        return data;
    }
    /**
     * 微信支付
     * mchCreateIp APP和网页支付提交用户端ip
     * infoId 产品唯一Id
     * tradeNo 支付流水号
     */
    @RequestMapping(value = "/wxPay/getCodeUrl", method = RequestMethod.POST)
    @ResponseBody
    public JSONObject wxPayGetCodeUrl(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> reqMap) throws Exception {

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(String.valueOf(reqMap.get("frontSysCode")));
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        if (result.get("errorCode").equals("F")){
            throw new BusinessException("此系统有误：" + result.get("errorMsg"));
        }

        String remoteAddr = request.getRemoteAddr();
        String mchCreateIp = String.valueOf(reqMap.get("mchCreateIp"));
        String infoId = String.valueOf(reqMap.get("infoId"));
        String tradeNo = String.valueOf(reqMap.get("tradeNo"));
        String type = String.valueOf(reqMap.get("type")); // type  用来区分是 0-APP端  1-WEB端
        if (Validator.isNull(tradeNo) || Validator.isNull(infoId) || Validator.isNull(mchCreateIp) || Validator.isNull(type) ) {
            throw new BusinessException("【tradeNo】或者【infoId】或者【mchCreateIp】或者【type】不能为空！！！");
        }
        log.info("remoteAddr---"+remoteAddr+"</br>mchCreateIp---"+mchCreateIp+"</br>infoId---"+infoId+"</br>tradeNo---"+tradeNo);
        Map<String, String> resultWebData = wxPayService.wxPayGetCodeUrl(mchCreateIp, infoId, tradeNo,type);

        JSONObject resJson = JSONObject.fromObject(resultWebData);
        return resJson;
    }

    /**
     * 小程序调用微信预支付
     * mchCreateIp APP和网页支付提交用户端ip
     * infoId 产品唯一Id
     * tradeNo 支付流水号
     * openId 用户在此小程序唯一标识
     */
    @RequestMapping(value = "/wxPay/miniProgram", method = RequestMethod.POST)
    @ResponseBody
    public JSONObject wxPayMiniProgram(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> reqMap) throws Exception {

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(String.valueOf(reqMap.get("frontSysCode")));
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        if (result.get("errorCode").equals("F")){
            throw new BusinessException("此系统有误：" + result.get("errorMsg"));
        }

        String remoteAddr = request.getRemoteAddr();
        String mchCreateIp = String.valueOf(reqMap.get("mchCreateIp"));
        String infoId = String.valueOf(reqMap.get("infoId"));
        String tradeNo = String.valueOf(reqMap.get("tradeNo"));
        String openId = String.valueOf(reqMap.get("openId"));
        if (Validator.isNull(tradeNo) || Validator.isNull(infoId) || Validator.isNull(mchCreateIp)|| Validator.isNull(openId)) {
            throw new BusinessException("【tradeNo】或者【infoId】或者【mchCreateIp】或者【openId】不能为空！！！");
        }
        log.info("remoteAddr---"+remoteAddr+"\n mchCreateIp---"+mchCreateIp+"\n infoId---"+infoId+"\n tradeNo---"+tradeNo+"\n openId---"+openId);
        Map<String, String> resultWebData = wxPayService.wxPayMiniProgram(mchCreateIp, infoId, tradeNo,openId);

        JSONObject resJson = JSONObject.fromObject(resultWebData);
        return resJson;
    }


    /**
     * APP调用微信预支付下单
     * mchCreateIp APP和网页支付提交用户端ip
     * infoId 产品唯一Id
     * tradeNo 支付流水号
     * appId 微信开放平台审核通过的移动应用AppID
     */
    @RequestMapping(value = "/wxPay/appProgram", method = RequestMethod.POST)
    @ResponseBody
    public JSONObject wxPayAppProgram(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> reqMap) throws Exception {

        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(String.valueOf(reqMap.get("frontSysCode")));
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        if (result.get("errorCode").equals("F")){
            throw new BusinessException("此系统有误：" + result.get("errorMsg"));
        }

        String remoteAddr = request.getRemoteAddr();
        String mchCreateIp = String.valueOf(reqMap.get("mchCreateIp"));
        String infoId = String.valueOf(reqMap.get("infoId"));
        String tradeNo = String.valueOf(reqMap.get("tradeNo"));
        String appId = String.valueOf(reqMap.get("appId"));
        if (Validator.isNull(tradeNo) || Validator.isNull(infoId) || Validator.isNull(mchCreateIp)|| Validator.isNull(appId)) {
            throw new BusinessException("【tradeNo】或者【infoId】或者【mchCreateIp】或者【appId】不能为空！！！");
        }
        log.info("remoteAddr---"+remoteAddr+"\n mchCreateIp---"+mchCreateIp+"\n infoId---"+infoId+"\n tradeNo---"+tradeNo+"\n appId---"+appId);
        Map<String, String> resultWebData = wxPayService.wxPayAppProgram(mchCreateIp, infoId, tradeNo,appId);

        JSONObject resJson = JSONObject.fromObject(resultWebData);
        return resJson;
    }

    /**
     * 保融支付通知接口
     * @param request
     * @param response
     */
    @RequestMapping(value = "/wxPay/notify", method = { RequestMethod.POST})
    @ResponseBody
    public void wxPayNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            log.info("-----保融通知接口----statr");
            wxPayService.wxPayNotify(request,response);
            log.info("-----保融通知接口----end");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * app支付--收银台方式
     * @param request
     * @param response
     */
    @RequestMapping(value = "/wxPay/appPay", method = { RequestMethod.POST})
    @ResponseBody
    public JSONObject appPay(HttpServletRequest request, HttpServletResponse response,@RequestBody Map<String, Object> reqMap) {
        //校验此前端系统是否存在且有效
        String frontSysCode = StrUtil.doNull(String.valueOf(reqMap.get("frontSysCode")));
        Map<String,String> result =  checkedFrontSysService.checkedSysByFrontSysCode(frontSysCode);
        if (result.get("errorCode").equals("F")){
            throw new BusinessException("此系统有误：" + result.get("errorMsg"));
        }

        String infoId = String.valueOf(reqMap.get("infoId"));
        String tradeNo = String.valueOf(reqMap.get("tradeNo"));
        if (Validator.isNull(tradeNo)  || Validator.isNull(infoId)) {
            throw new BusinessException("【tradeNo】或者【infoId】不能为空！！！");
        }
        log.info("tradeNo---"+tradeNo+"</br>infoId---"+infoId);
        com.alibaba.fastjson.JSONObject resultWebData = appPayService.appPay(tradeNo,infoId);

        JSONObject resJson = JSONObject.fromObject(resultWebData);
        return resJson;
    }


}


